// ModelViewer.tsx
import React, { useEffect, useRef } from'react';
import { Canvas, useLoader, useFrame } from '@react-three/fiber';
import { OrbitControls } from '@react-three/drei';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
import * as THREE from 'three';
import { useSelector, useDispatch } from'react-redux';
import { switchAnimation, RootState } from './store';

// 模型路径
const modelUrl = '/public/models/lazy.glb';
// 动画过渡时间（秒）
const TRANSITION_TIME = 0.5;

const ModelViewer: React.FC = () => {
    const modelRef = useRef<THREE.Group>(null);
    const [mixer, setMixer] = React.useState<THREE.AnimationMixer | null>(null);
    const [actions, setActions] = React.useState<THREE.AnimationAction[]>([]);
    const dispatch = useDispatch();
    const activeAnimationIndex = useSelector((state: RootState) => state.animation.activeAnimationIndex);
    const [prevAnimationIndex, setPrevAnimationIndex] = React.useState(0);
    const [transitionStartTime, setTransitionStartTime] = React.useState<number | null>(null);

    // 加载模型
    const gltf = useLoader(GLTFLoader, modelUrl);

    useEffect(() => {
        if (gltf.animations.length > 0 && modelRef.current) {
            const newMixer = new THREE.AnimationMixer(modelRef.current);
            const newActions = gltf.animations.map((clip) => {
                const action = newMixer.clipAction(clip);
                action.enabled = true;
                action.setEffectiveTimeScale(1);
                action.setEffectiveWeight(0);
                return action;
            });
            // 激活第一个动画
            newActions[0].setEffectiveWeight(1).play();
            setMixer(newMixer);
            setActions(newActions);
        }
    }, [gltf.animations]);

    // 每帧更新动画
    useFrame((_, delta) => {
        if (mixer) {
            mixer.update(delta);
        }

        // 处理动画过渡
        if (transitionStartTime!== null) {
            const elapsedTime = performance.now() - transitionStartTime;
            const progress = Math.min(elapsedTime / (TRANSITION_TIME * 1000), 1);

            const currentAction = actions[activeAnimationIndex];
            const prevAction = actions[prevAnimationIndex];

            if (currentAction && prevAction) {
                currentAction.setEffectiveWeight(progress);
                prevAction.setEffectiveWeight(1 - progress);

                if (progress >= 1) {
                    // 过渡完成
                    setTransitionStartTime(null);
                }
            }
        }
    });

    // 切换动画
    useEffect(() => {
        if (actions.length > 0) {
            setPrevAnimationIndex(activeAnimationIndex);
            setTransitionStartTime(performance.now());
        }
    }, [activeAnimationIndex, actions]);

    return (
        <Canvas> 
            <primitive ref={modelRef} object={gltf.scene} scale={1} position={[0, -1, 0]} />
            </Canvas>
            <div style={{ position: 'absolute', top: '10px', left: '10px' }}>
                {actions.map((_, index) => (
                    <button
                        key={index}
                        onClick={() => dispatch(switchAnimation(index))}
                        disabled={index === activeAnimationIndex}
                    >
                        Animation {index + 1}
                    </button>
                ))}
            </div>
            <OrbitControls />
        
    );
};

export default ModelViewer;